S3バケットポリシーで別組織IDを許可してアップロードできるか試してみた
はじめに
マルチアカウント運用が一般的になっている中、クロスアカウントでのS3アップロードは頻繁におこなっている環境も多いと思います。 よくあるパターンで言えば、Control Towerなどでセットアップしたログアーカイブ用のアカウントにログを出力するケースなどが思いつきますね。
この時、S3バケット側のバケットポリシーの制御方法としては組織IDをConditionで縛ることが多いですよね。こうすることで、今後組織内に払い出されるアカウントが増えても、バケットポリシー側には手を加えずに済むのがメリットです。
今回は、アカウントが所属している組織ID以外についても制御ができるのか? と疑問に思ったのでやってみました。やりたいイメージはこんな感じです。
バケットポリシーに組織2(o-yyyyyyyyyy)の組織IDを追加して、メンバーBアカウントからファイルをアップロードしてみます。
やってみる
以下3アカウントでやっていきます。アカウントを行き来するので、間違えないように注意してください。
- ログアーカイブ(組織1)
- メンバーA(組織1)
- メンバーB(組織2)
S3バケットの作成
ログアーカイブアカウントに保存先のS3バケットを作成します。
バケットポリシーに以下を設定して、他はデフォルトにします。 S3バケット名と組織IDは適宜置き換えてください。
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::${S3バケット名}", "arn:aws:s3:::${S3バケット名}/*" ], "Condition": { "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": "o-xxxxxxxxxx/*" } } } ] }
組織内からのアップロード
確認のため、メンバーAのアカウントから同じ組織内のログアーカイブアカウントに対して、ファイルをアップロードしてみます。
CloudShellで適当なテストファイルを作成して、以下コマンドを実行します。
$ touch testA.txt $ aws s3 cp testA.txt s3://{S3バケット名} upload: ./testA.txt to s3://{S3バケット名}/testA.txt
ログアーカイブアカウントでS3バケットを確認すると、問題なくアップロードができています。
組織外からのアップロード
それでは組織2(o-yyyyyyyyyy)から同じ手順でアップロードしてみます。
メンバーBにログインし、以下コマンドをCloudShellから実行します。
$ touch testB.txt $ aws s3 cp testB.txt s3://{S3バケット名} upload failed: ./testB.txt to {S3バケット名}/testB.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
バケットポリシーを変更していないので、Access Deniedのエラーとなりました。
このままではアップロードできないことが確認できたので、次に組織1のログアーカイブアカウントのバケットポリシーを変更します。
組織2(o-yyyyyyyyyy)を許可したいので、aws:PrincipalOrgPaths
に組織IDを追加しました。
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::${S3バケット名}", "arn:aws:s3:::${S3バケット名}/*" ], "Condition": { "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": [ "o-xxxxxxxxxx/*", "o-yyyyyyyyyy/*" ] } } } ] }
おさらいですが、これで以下の図の状態になりました。
それではメンバーBから再度アップロードを試してみます。
$ aws s3 cp testB.txt s3://{S3バケット名} upload: ./testB.txt to s3://{S3バケット名}/testB.txt
今度はAccess Deniedのエラーが発生しませんでしたね。 無事アップロードできたようなので、ログアーカイブアカウントでもS3バケットを確認してみます。
問題なくS3バケット側でもアップロードしたtestB.txt
が確認できました。
まとめ
組織をまたがったS3アップロードについて試してみました。
バケットポリシーに設定したaws:PrincipalOrgPaths
が所属している組織ID以外を認識してくれるのか?という疑問があったのですが、問題なく設定できるようで安心しました。
ユースケースですがアカウントを移行する際など、ログの出力先を移行前に変更したいケースなどで活用できるかと思います。
このブログが少しでも参考になれば幸いです。